import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart' show kIsWeb;

class HttpUtil {
  static const int defaultTimeout = 30000;

  static Future<HttpResponse> request({
    required String method,
    required String url,
    Map<String, dynamic>? data,
    Map<String, String>? headers,
    int timeoutMs = defaultTimeout,
  }) async {
    try {
      final requestHeaders = _prepareHeaders(headers);

      final body = data != null ? json.encode(data) : null;

      final client = http.Client();
      final timeoutDuration = Duration(milliseconds: timeoutMs);

      http.Response response;
      switch (method.toUpperCase()) {
        case 'GET':
          final uri = Uri.parse(url);
          final queryParams = data?.map(
            (key, value) => MapEntry(key, value.toString()),
          );
          final finalUri = queryParams != null && queryParams.isNotEmpty
              ? uri.replace(queryParameters: queryParams)
              : uri;

          response = await client
              .get(finalUri, headers: requestHeaders)
              .timeout(timeoutDuration);
          break;

        case 'POST':
          response = await client
              .post(Uri.parse(url), headers: requestHeaders, body: body)
              .timeout(timeoutDuration);
          break;

        default:
          throw HttpException('不支持的HTTP方法: $method');
      }

      return _handleResponse(response);
    } on SocketException catch (e) {
      String message;
      if (kIsWeb) {
        message = '网络请求失败，可能是CORS限制。请检查: ${e.message}';
      } else {
        message = '网络连接错误，请检查网络设置: ${e.message}';
      }

      return HttpResponse(
        success: false,
        statusCode: 0,
        data: null,
        message: message,
      );
    } on http.ClientException catch (e) {
      String message;
      if (kIsWeb && e.message.contains('XMLHttpRequest')) {
        message = '跨域请求被浏览器阻止。请检查服务器CORS设置: ${e.message}';
      } else {
        message = '网络请求失败，请稍后重试: ${e.message}';
      }

      return HttpResponse(
        success: false,
        statusCode: 0,
        data: null,
        message: message,
      );
    } catch (e) {
      return HttpResponse(
        success: false,
        statusCode: 0,
        data: null,
        message: '发生未知错误: $e',
      );
    }
  }

  static Map<String, String> _prepareHeaders(Map<String, String>? headers) {
    final defaultHeaders = {
      'Content-Type': 'application/json; charset=UTF-8',
      'Accept': 'application/json',
    };
    return {...defaultHeaders, ...?headers};
  }

  static HttpResponse _handleResponse(http.Response response) {
    dynamic responseData;
    try {
      responseData = json.decode(response.body);
    } catch (e) {
      responseData = response.body;
    }

    if (response.statusCode >= 200 && response.statusCode < 300) {
      return HttpResponse(
        success: true,
        statusCode: response.statusCode,
        data: responseData,
        message: '请求成功',
      );
    } else {
      String errorMessage;
      switch (response.statusCode) {
        case 400:
          errorMessage = '请求参数错误';
          break;
        case 401:
          errorMessage = '未授权，请重新登录';
          break;
        case 403:
          errorMessage = '拒绝访问';
          break;
        case 404:
          errorMessage = '请求的资源不存在';
          break;
        case 500:
          errorMessage = '服务器内部错误';
          break;
        case 502:
          errorMessage = '网关错误';
          break;
        case 503:
          errorMessage = '服务不可用';
          break;
        case 504:
          errorMessage = '网关超时';
          break;
        default:
          errorMessage = '请求失败，状态码: ${response.statusCode}';
      }

      return HttpResponse(
        success: false,
        statusCode: response.statusCode,
        data: responseData,
        message: errorMessage,
      );
    }
  }

  static Future<HttpResponse> get({
    required String url,
    Map<String, dynamic>? data,
    Map<String, String>? headers,
    int timeoutMs = defaultTimeout,
  }) {
    return request(
      method: 'GET',
      url: url,
      data: data,
      headers: headers,
      timeoutMs: timeoutMs,
    );
  }

  static Future<HttpResponse> post({
    required String url,
    Map<String, dynamic>? data,
    Map<String, String>? headers,
    int timeoutMs = defaultTimeout,
  }) {
    return request(
      method: 'POST',
      url: url,
      data: data,
      headers: headers,
      timeoutMs: timeoutMs,
    );
  }
}

class HttpResponse {
  final bool success;
  final int statusCode;
  final dynamic data;
  final String message;

  HttpResponse({
    required this.success,
    required this.statusCode,
    required this.data,
    required this.message,
  });

  @override
  String toString() {
    return 'HttpResponse{success: $success, statusCode: $statusCode, data: $data, message: $message}';
  }
}
